import json
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.patches import Ellipse
import numpy as np
from 翻译包 import *
from 文件工具箱 import *
from 句段处理 import *

数据文件 = "./分析结果.json"

def 画线形图(测量指标, 纵坐标标签, 标签横坐标 = 1.0):
	global 数据文件
	输出("测量指标:%s" % 测量指标)
	分析结果 = 恢复数据结构(数据文件) 
	数据 = 字典()
	for 算法 in ["hf", "hp", "pr", "el", "fr"]:
		数据[算法] = []
		for 内存容量 in np.arange(1.0, 10.1, 1.0):
			数据[算法].append(分析结果[算法][字符串(内存容量)][测量指标])
	输出("sf:%.3f" % 分析结果["sf"][测量指标])	
	临变 = zip(np.arange(1.0, 10.1, 1.0), 数据["hf"], \
			数据["hp"], 数据["pr"], 数据["el"], 数据["fr"])
	for 带宽, hf, hp, pr, el, fr in 临变:
		输出("带宽:%.1f, hf:%.3f, hp:%.3f, pr:%.3f, el:%.3f, fr:%.3f" % \
			(带宽, hf, hp, pr, el, fr))

	plt.figure()
#	if [] != 纵坐标范围:
#		plt.ylim(纵坐标范围)
	plt.xticks([2.0, 4.0, 6.0, 8.0, 10.0])
#	plt.yticks(np.arange(0.0, 1.01, 0.2))
	横坐标 = np.arange(1.0, 10.1, 1.0)
	plt.plot(横坐标, [分析结果["sf"][测量指标]]*10, color = 'red')
	plt.text(标签横坐标, 分析结果["sf"][测量指标] + 0.05, "SF", fontsize=20, bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 3})
	plt.plot(横坐标, 数据["hf"], label = "HF", marker = "o", color = 'green')
	plt.plot(横坐标, 数据["hp"], label = "HP", marker = "P", color = 'black')
	plt.plot(横坐标, 数据["fr"], label = "FR", marker = "s", color = 'orange')
	plt.plot(横坐标, 数据["pr"], label = "PR", marker = "d", color = 'purple')
	plt.plot(横坐标, 数据["el"], label = "EL", marker = "p", color = 'brown')
	plt.legend(bbox_to_anchor=(0.0, 1.0, 1.0, 0.1), loc = 3, ncol = 2, mode = "expand", borderaxespad = 0.0)
#	plt.legend(ncol = 2)
	plt.xlabel(r"Memory Consumption/MB")
	plt.ylabel(纵坐标标签)
	plt.savefig("%s.pdf" % 测量指标, bbox_inches = "tight")
	plt.close()

def 画柱状图(测量指标, 纵坐标范围, 纵坐标标签):
	global 数据文件
	测量结果 = 恢复数据结构(数据文件) 
	sf = []
	fr = []
	hf = []
	hp = []
	el = []
	pr = []
	for 数据集 in ["caida", "tsinghua", "hgc", "telecom"]:
		sf.append(测量结果[数据集]["sf"][测量指标])
		fr.append(测量结果[数据集]["fr"][测量指标])
		hf.append(测量结果[数据集]["hf"][测量指标])
		hp.append(测量结果[数据集]["hp"][测量指标])
		el.append(测量结果[数据集]["el"][测量指标])
		pr.append(测量结果[数据集]["pr"][测量指标])

	for 数据集, _sf, _fr, _hf, _hp, _pr, _el in \
		zip(["CD", "TH", "GC", "CT"], sf, fr, hf, hp, pr, el):
		输出("数据集:%s, sf:%.4f, fr:%.4f, hf:%.4f, hp:%.4f, pr:%.4f, el:%.4f" \
			% (数据集, _sf, _fr, _hf, _hp, _pr, _el))
		输出("(_sf-_el)/_el:%.3f" % ((_sf-_el)/_el))
	fig = plt.figure(1)
	ax = fig.add_axes([0,0,1,1])
	ax.set_xlim([0.5,4.5])
	ax.set_ylim(纵坐标范围)
	plt.ylabel(纵坐标标签)
	plt.xticks(range(1, 5), ["CAIDA", "Campus", "ISP1", "ISP2"])
	rects = ax.patches
	plt.bar(np.arange(1, 5) - 0.375, sf, label = "SF", color = 'red', \
			width = 0.15, hatch = "o")
	plt.bar(np.arange(1, 5) - 0.225, fr, label = "FR", color = 'green', \
			width = 0.15, hatch = "/")
	plt.bar(np.arange(1, 5) - 0.075, hf, label = "HF", color = 'purple', \
			width = 0.15, hatch = "\\")
	plt.bar(np.arange(1, 5) + 0.075, hp, label = "HP", color = 'blue', \
			width = 0.15, hatch = "+")
	plt.bar(np.arange(1, 5) + 0.225, el, label = "EL", color = 'magenta', \
			width = 0.15, hatch = "-")
	plt.bar(np.arange(1, 5) + 0.375, pr, label = "PR", color = 'yellow', \
			width = 0.15, hatch = "x")
	plt.legend(bbox_to_anchor=(0.0, 1.0, 1.0, 0.1), loc = 3, ncol = 3, mode = "expand", borderaxespad = 0.0)
#	plt.legend(ncol = 3)
	plt.xlabel("Traces")
	plt.ylabel(纵坐标标签)
	plt.savefig("%s.pdf" % 测量指标, bbox_inches = "tight")
	plt.close()

def 画散点图(测量指标, 纵坐标范围, 纵坐标标签):
	global 数据文件
	测量结果 = 恢复数据结构(数据文件) 
	数据 = 字典()
	for 算法 in ["sf", "fr", "hf", "hp", "pr", "el"]:
		数据[算法] = []
		for 数据集 in ["caida", "tsinghua", "hgc", "telecom"]:
			for 协议 in ["ipv4", "ipv6"]:
				数据[算法].append(测量结果[".".join([数据集, 协议])][算法][测量指标])
	for 数据集 in ["caida", "tsinghua", "hgc", "telecom"]:
		for 协议 in ["ipv4", "ipv6"]:
			临时变量 = ".".join([数据集, 协议])
			输出("%13s" % 临时变量, end=", ")
			for 算法 in ["sf", "fr", "hf", "hp", "pr", "el"]:
				输出("%s:%.4f" % (算法, 测量结果[临时变量][算法][测量指标]), end = ", ")
			比值1 = (测量结果[临时变量]["sf"][测量指标] - 测量结果[临时变量]["hf"][测量指标])/测量结果[临时变量]["hf"][测量指标]
			比值2 = (测量结果[临时变量]["sf"][测量指标] - 测量结果[临时变量]["hp"][测量指标])/测量结果[临时变量]["hp"][测量指标]
			输出("\nsf/hf:%.4f, sf/hp:%.4f" % (比值1, 比值2))
				

	fig = plt.figure(1)
	ax = fig.add_axes([0,0,1,1])
	ax.set_xlim([0, 9])
	if [] != 纵坐标范围:
		ax.set_ylim(纵坐标范围)
	plt.ylabel(纵坐标标签)
	横坐标 = 范围(1, 9)
	标签 = [r"CAIDA$_{v4}$", r"CAIDA$_{v6}$", r"Cmps$_{v4}$", r"Cmps$_{v6}$", \
		   r"ISP1$_{v4}$", r"ISP1$_{v6}$", r"ISP2$_{v4}$", r"ISP2$_{v6}$"]
	plt.xticks(横坐标, 标签, rotation = 35)
	rects = ax.patches
	图标大小 = 400
	线条宽度 = 2.0
	plt.grid(linestyle = ":")
	plt.scatter(横坐标, 数据["sf"], label = "SF", color = 'red', \
		linewidths = 线条宽度, marker="^", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["fr"], label = "FR", color = 'orange', \
		linewidths = 线条宽度, marker="s", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["hf"], label = "HF", color = 'green', \
		linewidths = 线条宽度, marker="o", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["hp"], label = "HP", color = 'black', \
		linewidths = 线条宽度, marker="P", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["pr"], label = "PR", color = 'purple', \
		linewidths = 线条宽度, marker="d", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["el"], label = "EL", color = 'brown', \
		linewidths = 线条宽度, marker="p", s = 图标大小, facecolors="none")
	plt.legend(bbox_to_anchor=(0.0, 1.0, 1.0, 0.1), loc = 3, ncol = 3, mode = "expand", borderaxespad = 0.0)
#	plt.legend(ncol = 2)
	plt.xlabel("Traces")
	plt.ylabel(纵坐标标签)
	plt.savefig("%s.pdf" % 测量指标, bbox_inches = "tight")
	plt.close()

def 画升级比例():
	global 数据文件
	测量结果 = 恢复数据结构(数据文件) 
	数据 = 字典()
	for 算法 in ["sf", "hf", "pr"]:
		数据[算法] = []
		for 数据集 in ["caida", "tsinghua", "hgc", "telecom"]:
			for 协议 in ["ipv4", "ipv6"]:
				数据[算法].append(测量结果[".".join([数据集, 协议])][算法]["promotion_ratio"])

	for 数据集 in ["caida", "tsinghua", "hgc", "telecom"]:
		for 协议 in ["ipv4", "ipv6"]:
			输出("%8s.%s: " % (数据集, 协议), end="")
			for 算法 in ["sf", "hf", "pr"]:
				升级频率 = 测量结果[".".join([数据集, 协议])][算法]["promotion_ratio"]
				输出("%s=%.4f, " % (算法, 升级频率), end="")
			输出()

	输出(数据["sf"])
	输出(数据["hf"])
	输出(数据["pr"])
	fig = plt.figure(1)
	横坐标 = 范围(1, 9)
	plt.xlabel("Traces")
	plt.ylabel("Promotion Ratio")
	标签 = [r"CAIDA$_{v4}$", r"CAIDA$_{v6}$", r"Cmps$_{v4}$", r"Cmps$_{v6}$", \
		   r"ISP1$_{v4}$", r"ISP1$_{v6}$", r"ISP2$_{v4}$", r"ISP2$_{v6}$"]
	plt.xticks(横坐标, 标签, rotation = 35)
	plt.grid(linestyle = ":")
	图标大小 = 400
	线条宽度 = 2.0
	plt.scatter(横坐标, 数据["sf"], label = "SF", color = 'orange', \
		linewidths = 线条宽度, marker="s", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["hf"], label = "HF", color = 'green', \
		linewidths = 线条宽度, marker="o", s = 图标大小, facecolors="none")
	plt.scatter(横坐标, 数据["pr"], label = "PR", color = 'purple', \
		linewidths = 线条宽度, marker="d", s = 图标大小, facecolors="none")
	plt.legend(bbox_to_anchor=(0.0, 1.0, 1.0, 0.1), loc = 3, ncol = 2, mode = "expand", borderaxespad = 0.0)
#	plt.legend(ncol = 2)
	plt.savefig("promotion_ratio.pdf", bbox_inches = "tight")
	plt.savefig("promotion_ratio.png", bbox_inches = "tight")
	plt.savefig("promotion_ratio.eps", bbox_inches = "tight")
	plt.close()

def 大流碎片数绘图():
	真实流集 = 恢复数据结构("./真实流集.json")
	大流数 = 字典()
	for 流长度 in 真实流集.values():
		for 阈值 in 范围(10, 101, 10):
			if 阈值 not in 大流数:
				大流数[阈值] = 0
			if 流长度 >= 阈值:
				大流数[阈值] += 1
	大流碎片数 = 恢复数据结构("./带宽消耗和大流碎片数.json")
	数据 = 字典()
	for 阈值 in 范围(10, 101, 10):
		for 算法 in ["SuperFlow", "FlowRadar", "HashFlow", "HashPipe", "Elastic", "PRECISION"]:
			if 算法 not in 数据:
				数据[算法] = []
			数据[算法].append(大流碎片数["IPv4"][算法][句段(阈值)]["大流碎片数"]/\
					浮数(大流数[阈值]))

	for 子项 in zip(范围(10, 101, 10), 数据["SuperFlow"], 数据["FlowRadar"], 数据["HashFlow"],\
			数据["HashPipe"], 数据["Elastic"], 数据["PRECISION"]):
		输出("阈值:%d, sf:%.2f, fr:%.2f, hf:%.2f, hp:%.2f, el:%.2f, pr:%.2f" % 子项)
	plt.figure()
	plt.xticks(范围(20, 101, 20))
	横坐标 = 范围(10, 101, 10)
	plt.plot(横坐标, 数据["SuperFlow"], label = "SF", marker = "^", markerfacecolor="none", 
			markersize=markersize, color = 'red')
	plt.plot(横坐标, 数据["HashFlow"], label = "HF", marker = "o", markerfacecolor="none", 
			markersize=markersize, color = 'green')
	plt.plot(横坐标, 数据["HashPipe"], label = "HP", marker = "P", markerfacecolor="none", 
			markersize=markersize, color = 'black')
	plt.plot(横坐标, 数据["FlowRadar"], label = "FR", marker = "s", markerfacecolor="none", 
			markersize=markersize, color = 'orange')
	plt.plot(横坐标, 数据["PRECISION"], label = "PR", marker = "d", markerfacecolor="none", 
			markersize=markersize, color = 'purple')
	plt.plot(横坐标, 数据["Elastic"], label = "EL", marker = "p", markerfacecolor="none", 
			markersize=markersize, color = 'brown')
	plt.legend(bbox_to_anchor=(0.0, 1.0, 1.0, 0.1), loc = 3, ncol = 2, mode = "expand", borderaxespad = 0.0)
	plt.xlabel(r"Threshold/packets")
	plt.ylabel("Segment/Flow Ratio")
	plt.savefig("n_segments_elephant_flow.pdf", bbox_inches = "tight")
	plt.close()


def 带宽绘图():
	带宽消耗 = 恢复数据结构("./带宽消耗和大流碎片数.json")
	时间 = 20.0 # sec
	sf = []
	fr = []
	hf = []
	hp = []
	el = []
	pr = []
	for 阈值 in 范围(10, 101, 10):
		sf.append(带宽消耗["IPv4"]["SuperFlow"][句段(阈值)]["导出次数"]*168/时间/(10**8))
		fr.append((带宽消耗["IPv4"]["FlowRadar"][句段(阈值)]["数平导出次数"] + 1)\
			*152*20480/时间/(10**8))
		hf.append((带宽消耗["IPv4"]["HashFlow"][句段(阈值)]["数平导出次数"] + 1)\
			*136*28672/时间/(10**8))
		hp.append((带宽消耗["IPv4"]["HashPipe"][句段(阈值)]["数平导出次数"] + 1)\
			*136*30720/时间/(10**8))
		el.append((带宽消耗["IPv4"]["Elastic"][句段(阈值)]["数平导出次数"] + 1)\
			*169*22528/时间/(10**8))
		pr.append((带宽消耗["IPv4"]["PRECISION"][句段(阈值)]["数平导出次数"] + 1)\
			*136*30720/时间/(10**8))

	数据 = zip(范围(10, 101, 10), sf, fr, hf, hp, el, pr)
	for 子项 in 数据:
		输出("阈值:%d, sf:%.2f, fr:%.2f, hf:%.2f, hp:%.2f, el:%.2f, pr:%.2f" % 子项)
	plt.figure()
	plt.xticks(范围(20, 101, 20))
#	plt.yticks(np.arange(0.0, 1.01, 0.2))
	横坐标 = 范围(10, 101, 10)
	plt.plot(横坐标, sf, label = "SF", marker = "^", markerfacecolor="none", 
			markersize=markersize, color = 'red')
	plt.plot(横坐标, hf, label = "HF", marker = "o", markerfacecolor="none", 
			markersize=markersize, color = 'green')
	plt.plot(横坐标, hp, label = "HP", marker = "P", markerfacecolor="none", 
			markersize=markersize, color = 'black')
	plt.plot(横坐标, fr, label = "FR", marker = "s", markerfacecolor="none", 
			markersize=markersize, color = 'orange')
	plt.plot(横坐标, pr, label = "PR", marker = "d", markerfacecolor="none", 
			markersize=markersize, color = 'purple')
	plt.plot(横坐标, el, label = "EL", marker = "p", markerfacecolor="none", 
			markersize=markersize, color = 'brown')
	plt.legend(bbox_to_anchor=(0.0, 1.0, 1.0, 0.1), loc = 3, ncol = 2, mode = "expand", borderaxespad = 0.0)
	plt.xlabel(r"Threshold/packets")
	plt.ylabel("BW Conspt./Mbps")
	plt.savefig("bandwidth_consumption.pdf", bbox_inches = "tight")
	plt.close()
	
if __name__ == "__main__":
	画线形图("wfsc", "WFSC")
	画线形图("ware", "WARE")
	画线形图("are", "ARE", 6.0)
	画线形图("fsc", "FSC")
	画线形图("wfsc2", "WFSC")
	画线形图("ware2", "WARE")
	画线形图("are2", "ARE", 6.0)
	画线形图("fsc2", "FSC")
